#include "prr.h"
#include "rectype.h"
#include "util.h"

#include "cnfield.h"
#include "cnfield.cpp"

#include "nmfield.h"
#include "nmarrfield.h"

#include "stdffield.h"
#include "stdffield.cpp"

#include <sstream>

using namespace std;
using namespace opsrc::stdf;

map<string,int> Prr::seq_count;

Prr::Prr()
{}

Prr::Prr(stdf_rec _stdfrec, int _reclen, std::ios::pos_type _fileRecFirstBytePosition, int _orderindex, endian e, char* buf)
:RecBase(_stdfrec, _reclen, _fileRecFirstBytePosition, _orderindex), en(e) {
    if (buf!=0)
        readFields(buf);
 }

Prr::~Prr() {
}

const StdfField<int> Prr::getHeadNumber() const {
    return head_num;
}

void Prr::setHeadNumber(StdfField<int> headnum) {
    head_num = headnum;
}

const StdfField<int> Prr::getSiteNumber() const {
    return site_num;
}

void Prr::setSiteNumber(StdfField<int> sitenum) {
    site_num = sitenum;
}

const StdfField<vector<bool> > Prr::getPartFlag() const {
    return part_flag;
}

void Prr::setPartFlag(StdfField<vector<bool> > partflag) {
    part_flag = partflag;
}

const StdfField<int> Prr::getNumberOfTests() const {
    return num_test;
}

void Prr::setNumberOfTests(StdfField<int> numtest) {
    num_test = numtest;
}

const StdfField<int> Prr::getHardBin() const {
    return hard_bin;
}

void Prr::setHardBin(StdfField<int> hardbin) {
    hard_bin = hardbin;
}

const StdfField<int> Prr::getSoftBin() const {
    return soft_bin;
}

void Prr::setSoftBin(StdfField<int> softbin) {
    soft_bin = softbin;
}

const StdfField<int> Prr::getXCoordinate() const {
    return x_coord;
}

void Prr::setXCoordinate(StdfField<int> xcoord) {
    x_coord = xcoord;
}

const StdfField<int> Prr::getYCoordinate() const {
    return y_coord;
}

void Prr::setYCoordinate(StdfField<int> ycoord) {
    y_coord = ycoord;
}

const StdfField<long> Prr::getTestTime() const {
    return test_t;
}

void Prr::setTestTime(StdfField<long> testt) {
    test_t = testt;
}

const StdfField<string> Prr::getPartId() const {
    return part_id;
}

void Prr::setPartId(StdfField<string> partid) {
    part_id = partid;
}

const StdfField<string> Prr::getPartText() const {
    return part_txt;
}

void Prr::setPartText(StdfField<string> parttxt) {
    part_txt = parttxt;
}

const StdfField<CharArray> Prr::getPartFix() const {
    return part_fix;
}

void Prr::setPartFix(StdfField<CharArray> partfix) {
    part_fix = partfix;
}

const int Prr::getSeqId() const {
    return seq_id;
}

void Prr::setSeqId(int seqid) {
    seq_id = seqid;
}

void Prr::readFields(char *buf) {

#if _DEBUG
    cout << "stdfrec= PRR , filebytestartposition= " <<   getFileRecByteStartPosition() << ", recbytecount= " << reclen <<endl;
#endif
    
    int curpos = 0;
    // Read Head num, 1 byte
    NmField<unsigned int, 1> headnum(buf+curpos, en);
    head_num.set(headnum.getData(), curpos, headnum.getByteCount(), headnum.getTotalByteCount());
    curpos += head_num.getTotalByteCount();

    // Read Site num, 1 byte
    if (curpos < reclen-1) {
        NmField<unsigned int, 1> sitenum(buf+curpos, en);
        site_num.set(sitenum.getData(), curpos, sitenum.getByteCount(), sitenum.getTotalByteCount());
        curpos += site_num.getTotalByteCount();
    }

    // Read test flag
    if (curpos < reclen-1) {
        NmArrField<bool, 1 > partflag(buf+curpos, en,1 );
        part_flag.set(partflag.getData(), curpos, partflag.getByteCount(), partflag.getTotalByteCount());
        curpos += part_flag.getTotalByteCount();
    }

    // Read number of test, U2 byte
    if (curpos < reclen-1) {
        NmField<unsigned int, 2> numtest(buf+curpos, en);
        num_test.set(numtest.getData(), curpos, numtest.getByteCount(), numtest.getTotalByteCount());
        curpos += num_test.getTotalByteCount();
    }

    // Read hardbin number, U2
    if (curpos < reclen-1) {
        NmField<unsigned int, 2> hardbin(buf+curpos, en);
        hard_bin.set(hardbin.getData(), curpos, hardbin.getByteCount(), hardbin.getTotalByteCount());
        curpos += hard_bin.getTotalByteCount();
    }

    // Read softbin number, U2
    if (curpos < reclen-1) {
        NmField<unsigned int, 2> softbin(buf+curpos, en);
        soft_bin.set(softbin.getData(), curpos, softbin.getByteCount(), softbin.getTotalByteCount());
        curpos += soft_bin.getTotalByteCount();
    }

    // Read x coordinate number, I2
    if( curpos < reclen-1) {
        NmField<int, 2> xcoord(buf+curpos, en);
        x_coord.set(xcoord.getData(), curpos, xcoord.getByteCount(), xcoord.getTotalByteCount());
        curpos += x_coord.getTotalByteCount();
    }

    // Read y coordinate number, I2
    if (curpos < reclen-1) {
        NmField<int, 2> ycoord(buf+curpos, en);
        y_coord.set(ycoord.getData(), curpos, ycoord.getByteCount(), ycoord.getTotalByteCount());
        curpos += y_coord.getTotalByteCount();
    }

    // Read Test time, U4
    if (curpos < reclen-1) {
        NmField<long, 4> testt(buf+curpos, en);
        test_t.set(testt.getData(), curpos, testt.getByteCount(), testt.getTotalByteCount());
        curpos += test_t.getTotalByteCount();
    }

    // Read Part ID, string Cn
    if (curpos < reclen-1 ) {
        CnField<string> partid(buf+curpos, en);
        part_id.set(partid.getData(), curpos, partid.getByteCount(), partid.getTotalByteCount());
        curpos += part_id.getTotalByteCount();
    }

    // Read Part Description, string Cn
    if (curpos < reclen-1) {
        CnField<string> parttxt(buf+curpos, en);
        part_txt.set(parttxt.getData(), curpos, parttxt.getByteCount(), parttxt.getTotalByteCount());
        curpos += part_txt.getTotalByteCount();
    }

    // Read Part Fix, Bn type where 1st byte is byte length
    if (curpos < reclen-1) {
        CnField<CharArray> partfix(buf+curpos, en);
        part_fix.set(partfix.getData(), curpos, partfix.getByteCount(), partfix.getTotalByteCount());
    }

    // Compute Seq ID
    stringstream ss;
    ss << "PRR." << x_coord.getData() << "." << y_coord.getData();
    string key = ss.str();
    seq_count[key]++;
    seq_id = seq_count[key];
}
